﻿using GSI.Core;
using Microsoft.Win32;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace GSI.UI
{
	/// <summary>
	/// MainWindow.xaml 的交互逻辑
	/// </summary>
	public partial class MainWindow : Window
	{
		public bool IsReadData { get; set; }

		public MainWindow()
		{
			InitializeComponent();
			PrintImage.IsEnabled = false;
			pro.Visibility = Visibility.Hidden;
			pro.IsIndeterminate = true;
			this.IsReadData = false;
			bar.Stretch = Stretch.UniformToFill;
		}

		private void PrintImage_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.CPUP);
		}

		private void OpenFile_Click(object sender, RoutedEventArgs e)
		{
			if (CoreApp.ReadData())
			{
				this.IsReadData = true;
				PrintImage.IsEnabled = true;
				PrintImage_Click(sender, e);
			}
		}

		private static BitmapImage BitmapToBitmapImage(Bitmap bitmap)
		{
			using (MemoryStream stream = new MemoryStream())
			{
				bitmap.Save(stream, ImageFormat.Png); // 坑点：格式选Bmp时，不带透明度

				stream.Position = 0;
				BitmapImage result = new BitmapImage();
				result.BeginInit();
				// According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
				// Force the bitmap to load right now so we can dispose the stream.
				result.CacheOption = BitmapCacheOption.OnLoad;
				result.StreamSource = stream;
				result.EndInit();
				result.Freeze();
				return result;
			}
			//--------------------- 
			//作者：霍莉雪特
			//来源：CSDN
			//原文：https://blog.csdn.net/qq_18995513/article/details/53693554 
			//版权声明：本文为博主原创文章，转载请附上博文链接！
		}

		private static ImageSource ToImage(Bitmap bitmap)
		{
			ImageSource imageSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
					bitmap.GetHbitmap(),
				IntPtr.Zero,
				System.Windows.Int32Rect.Empty,
				BitmapSizeOptions.FromEmptyOptions());

			return imageSource;
		}

		private void button_k_s_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.CPUS);
		}

		private void button_k_p_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.CPUP);
		}

		private void button_k_cuda_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.GPUCuda);
		}

		private void button_Click(object sender, RoutedEventArgs e)
		{
			CoreApp.output = "";
			Output.Text = CoreApp.output;
		}

		private Core.Type? lastOption = null;

		private async void start(Core.Type type)
		{
			lastOption = type;
			if (!IsReadData)
			{
				IsReadData = CoreApp.ReadData();
			}
			if (!IsReadData)
			{
				Output.Text += "\n未读取到数据\n";
				return;
			}
			pro.Visibility = Visibility.Visible;
			var s = image.Parent as Grid;
			Bitmap bitmap = await Work(s.ActualWidth, s.ActualHeight, int.Parse(Jiange.Text), type);//　代码会停顿在这里，等待Work执行结束，但不会阻塞UI
																									//Bitmap bitmap = CoreApp.PrintImage(s.ActualWidth, s.ActualHeight, int.Parse(Jiange.Text),type);
			pro.Visibility = Visibility.Hidden;
			image.Source = ToImage(bitmap);
			bar.Source = ToImage(Core.CoreApp.PrintColorBar(((bar.Parent as Grid).ActualWidth) + 1.0, ((bar.Parent as Grid).ActualHeight) + 1.0));
			Output.Text =CoreApp.output;
			this.Output.ScrollToEnd();//滚动到光标处
		}

		private Task<Bitmap> Work(double actualWidth, double actualHeight, int v, Core.Type type)
		{
			return Task.Factory.StartNew(() =>
			{
				return CoreApp.PrintImage(actualWidth, actualHeight, v, type);
			});
		}

		private void button_IDW_s_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.IDW_CPU);
		}

		private void button_IDW_g_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.IDW_GPU);
		}

		private void button_IDW_p_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.IDW_Parallel);
		}

		private void button_k_cublas_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.GPUCublas);
		}

		private void button_k_opencl_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.GPUOpenCL);
		}

		private void button_k_test_Click(object sender, RoutedEventArgs e)
		{
			start(Core.Type.GPUMCublas);

		}

		private void image_MouseDown(object sender, MouseButtonEventArgs e)
		{
		}

		private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
		{
			//MessageBox.Show("窗口变化");
			if (lastOption != null)
				start(lastOption.Value);
		}

		private void image_MouseLeave(object sender, MouseEventArgs e)
		{
			this.label.Visibility = Visibility.Hidden;
		}

		private void image_MouseMove(object sender, MouseEventArgs e)
		{
			System.Windows.Point p =  e.GetPosition((IInputElement)sender);
			var v = CoreApp.GetValue(p.X, p.Y);
			if(v!=-1)
			{
			this.label.Content = " Value= " + v;
			this.label.Visibility = Visibility.Visible;
			}
			else
			{
				this.label.Visibility = Visibility.Hidden;
			}
		}

		private void Excel_Click(object sender, RoutedEventArgs e)
		{
			var infoes = CoreApp.Infoes;
			XSSFWorkbook workBook = new XSSFWorkbook();  //实例化XSSF
			XSSFSheet sheet = (XSSFSheet)workBook.CreateSheet();  //创建一个sheet

			IRow frow0 = sheet.CreateRow(0);  // 添加一行（一般第一行是表头）
			frow0.CreateCell(0).SetCellValue("计算协方差时间");
			frow0.CreateCell(1).SetCellValue("计算半方差时间");
			frow0.CreateCell(2).SetCellValue("计算矩阵乘时间");   
			frow0.CreateCell(3).SetCellValue("计算累加值时间");   
			frow0.CreateCell(4).SetCellValue("计算累计总时间");   
			frow0.CreateCell(5).SetCellValue("方法名称");   
			frow0.CreateCell(6).SetCellValue("测试时间");   

			for (int i = 0; i < infoes.Count; i++)  //循环添加list中的内容放到表格里
			{
				IRow frow1 = sheet.CreateRow(i+1);  //之所以从i+1开始 因为第一行已经有表头了
				frow1.CreateCell(0).SetCellValue(infoes[i].Time_Km);
				frow1.CreateCell(1).SetCellValue(infoes[i].Time_Dm);
				frow1.CreateCell(2).SetCellValue(infoes[i].Time_MM);
				frow1.CreateCell(3).SetCellValue(infoes[i].Time_Re);
				frow1.CreateCell(4).SetCellValue(infoes[i].Time_All);
				frow1.CreateCell(5).SetCellValue(infoes
								 [i].MethodType.ToString());
				frow1.CreateCell(6).SetCellValue(infoes[i].Time);
			}
			//选择数据文件窗口
			OpenFileDialog fileDialog = new OpenFileDialog();
			fileDialog.Title = "导出测试数据文件";
			fileDialog.Filter = "数据文件|*.xlsx";
			//要返回的数据列表
			//获取数据文件路径
			if (fileDialog.ShowDialog() == true)
			{
				var filePath = fileDialog.FileName;
				try
				{
					using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
					{
						workBook.Write(fs);  //写入文件
						workBook.Close();  //关闭
					}
					MessageBox.Show("导出成功");
				}
				catch (Exception)
				{
					workBook.Close();
				}

			}
		}
	}
}
